{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    8506\n",
       "1    6369\n",
       "2    5111\n",
       "3    2697\n",
       "4    3078\n",
       "5     409\n",
       "6     752\n",
       "7     165\n",
       "8    1752\n",
       "9    8132\n",
       "dtype: int64"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pandas import Series, DataFrame\n",
    "\n",
    "g = np.random.default_rng(0)\n",
    "s = Series(g.integers(0, 10000, 10))\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Beyond 1\n",
    "\n",
    "What if the range were from 0 - 10,000? How would that change your strategy, if at all?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    0\n",
       "1    6\n",
       "2    1\n",
       "3    9\n",
       "4    7\n",
       "5    0\n",
       "6    5\n",
       "7    6\n",
       "8    5\n",
       "9    3\n",
       "dtype: int8"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Our string strategy will work just fine here! If none of the numbers\n",
    "# are <10, then we can even remove the call to \"fillna\", but I think that \n",
    "# it's wiser to keep that around.\n",
    "\n",
    "s.astype(str).str.get(-2).fillna('0').astype(np.int8)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Beyond 2\n",
    "\n",
    "Given a range from 0 to 10,000, what's the smallest `dtype` we could use for our integers?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "165 8506\n"
     ]
    }
   ],
   "source": [
    "# Let's find the min and max values for our series:\n",
    "\n",
    "print(s.min(), s.max())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     58\n",
       "1    -31\n",
       "2     -9\n",
       "3   -119\n",
       "4      6\n",
       "5   -103\n",
       "6    -16\n",
       "7    -91\n",
       "8    -40\n",
       "9    -60\n",
       "dtype: int8"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# What happens if we use int8?\n",
    "s.astype(np.int8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     58\n",
       "1    225\n",
       "2    247\n",
       "3    137\n",
       "4      6\n",
       "5    153\n",
       "6    240\n",
       "7    165\n",
       "8    216\n",
       "9    196\n",
       "dtype: uint8"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# What happens if we use uint8?\n",
    "s.astype(np.uint8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    8506\n",
       "1    6369\n",
       "2    5111\n",
       "3    2697\n",
       "4    3078\n",
       "5     409\n",
       "6     752\n",
       "7     165\n",
       "8    1752\n",
       "9    8132\n",
       "dtype: int16"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# So it seems we really need to use either np.int16 or np.uint16 to avoid problems!\n",
    "s.astype(np.int16)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Beyond 3\n",
    "\n",
    "Create a new series, with 10 floating-point values between 0 and 1,000. Find the numbers whose integer component (i.e., ignoring any fractional part) are even."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    209.429210\n",
       "1    950.023993\n",
       "2    565.990291\n",
       "3    125.967625\n",
       "4    857.917191\n",
       "5    966.625315\n",
       "6    176.835746\n",
       "7    951.227401\n",
       "8    143.765381\n",
       "9    747.060886\n",
       "dtype: float64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# First, create the series\n",
    "s = Series(np.random.rand(10) * 1000)\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    950.023993\n",
       "5    966.625315\n",
       "6    176.835746\n",
       "dtype: float64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get the modulus (dividing by 2) of the int version of the numbers\n",
    "# Check which results are 0, and use that as a mask index on s\n",
    "\n",
    "s[s.astype(np.int64) % 2 == 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
